using System;
using System.Collections.Generic;
using System.Xml;
using System.Drawing;

class AirportLayout {
	private String name;
	private String imgPath;
	private List<RunwayLayout> runways;
	private List<TaxiwayLayout> taxiways;
	
	public AirportLayout() {
		this.runways = new List<RunwayLayout>();
        this.taxiways = new List<TaxiwayLayout>();
		
		this.name = "Los Angeles International Airport (LAX)";
		this.imgPath = "Resources/LAXLayout.jpg";
	}

	public void AddRunway(RunwayLayout runway) {
        this.runways.Add(runway);
	}

	public void AddTaxiway(TaxiwayLayout taxiway) {
        this.taxiways.Add(taxiway);
	}

    public void DrawSurfaces(Graphics g) {
        foreach(RunwayLayout runway in this.runways) {
            runway.Draw(g);
        }

        foreach(TaxiwayLayout taxiway in this.taxiways) {
            taxiway.Draw(g);
        }
    }
	
	public String Name {
		get { return this.name; }
		set { this.name = value; }
	}
	
	public String ImgPath {
		get { return this.imgPath; }
		set { this.imgPath = value; }
	}
	
	public void SaveToFile() {
		XmlDocument xmlDoc = new XmlDocument();
		XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null); 
		
		// Create the root element
		XmlElement rootNode = xmlDoc.CreateElement("airport");
		rootNode.SetAttribute("name", this.name);
		rootNode.SetAttribute("imgPath", this.imgPath);
		xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement); 
		xmlDoc.AppendChild(rootNode);
		
		XmlElement dateBuiltNode = xmlDoc.CreateElement("dateBuilt");
		dateBuiltNode.AppendChild(xmlDoc.CreateTextNode(DateTime.Now.ToString()));
		rootNode.AppendChild(dateBuiltNode);
		
		XmlElement runwaysNode = xmlDoc.CreateElement("runways");

        this.runways.ForEach(delegate(RunwayLayout runway) {
			XmlElement runwayNode = xmlDoc.CreateElement("runway");
			
			runwayNode.SetAttribute("direction1", runway.Direction1);
			runwayNode.SetAttribute("direction2", runway.Direction2);
			
			XmlElement maxWeightNode = xmlDoc.CreateElement("maxWeight");
			XmlElement widthNode = xmlDoc.CreateElement("width");
			XmlElement arrivalsNode = xmlDoc.CreateElement("arrivals");
			XmlElement departuresNode = xmlDoc.CreateElement("departures");
			XmlElement labelLocationNode = xmlDoc.CreateElement("labelLocation");
			XmlElement nodesNode = xmlDoc.CreateElement("nodes");
			
			maxWeightNode.AppendChild(xmlDoc.CreateTextNode(runway.MaxWeight.ToString()));
            widthNode.AppendChild(xmlDoc.CreateTextNode(runway.Width.ToString()));
            arrivalsNode.AppendChild(xmlDoc.CreateTextNode((runway.Arrivals ? "1" : "0")));
            departuresNode.AppendChild(xmlDoc.CreateTextNode((runway.Departures ? "1" : "0")));
			labelLocationNode.AppendChild(xmlDoc.CreateTextNode(runway.LabelLocation.X + "," + runway.LabelLocation.Y));
			runway.Points.ForEach(delegate(Point point) {
                this.taxiways.ForEach(delegate(TaxiwayLayout taxiway) {
                    for(int i = 0; i < taxiway.Points.Count; i++) {
                        if(point != taxiway.Points[i] && Helper.DistanceBetween(point, taxiway.Points[i]) < 2.5) {
                            taxiway.Points[i] = point;
                        }
                    }
                });

				XmlElement nodeNode = xmlDoc.CreateElement("node");
				nodeNode.AppendChild(xmlDoc.CreateTextNode(point.X + "," + point.Y));
				nodesNode.AppendChild(nodeNode);
			});
			
			runwayNode.AppendChild(maxWeightNode);
			runwayNode.AppendChild(widthNode);
			runwayNode.AppendChild(arrivalsNode);
			runwayNode.AppendChild(departuresNode);
			runwayNode.AppendChild(labelLocationNode);
			runwayNode.AppendChild(nodesNode);
			
			runwaysNode.AppendChild(runwayNode);
        });
        
        rootNode.AppendChild(runwaysNode);
		
		XmlElement taxiwaysNode = xmlDoc.CreateElement("taxiways");

        this.taxiways.ForEach(delegate(TaxiwayLayout taxiway) {
			XmlElement taxiwayNode = xmlDoc.CreateElement("taxiway");
			
			taxiwayNode.SetAttribute("name", taxiway.Name);
			
			XmlElement maxWeightNode = xmlDoc.CreateElement("maxWeight");
			XmlElement widthNode = xmlDoc.CreateElement("width");
			XmlElement nodesNode = xmlDoc.CreateElement("nodes");
			
			maxWeightNode.AppendChild(xmlDoc.CreateTextNode(taxiway.MaxWeight.ToString()));
            widthNode.AppendChild(xmlDoc.CreateTextNode(taxiway.Width.ToString()));
            taxiway.Points.ForEach(delegate(Point point) {
                this.taxiways.ForEach(delegate(TaxiwayLayout thisTaxiway) {
                    if(taxiway.Name != thisTaxiway.Name) {
                        for(int i = 0; i < thisTaxiway.Points.Count; i++) {
                            if(point != thisTaxiway.Points[i] && Helper.DistanceBetween(point, thisTaxiway.Points[i]) < 2.5) {
                                thisTaxiway.Points[i] = point;
                            }
                        }
                    }
                });
            });

            taxiway.Points.ForEach(delegate(Point point) {
				XmlElement nodeNode = xmlDoc.CreateElement("node");
				nodeNode.AppendChild(xmlDoc.CreateTextNode(point.X + "," + point.Y));
				nodesNode.AppendChild(nodeNode);
			});
			
			taxiwayNode.AppendChild(maxWeightNode);
			taxiwayNode.AppendChild(widthNode);
			taxiwayNode.AppendChild(nodesNode);
			
			taxiwaysNode.AppendChild(taxiwayNode);
        });
        
        rootNode.AppendChild(taxiwaysNode);
		
		xmlDoc.Save(Console.Out);
    }
}